﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Services;
using Entities;
using WebUI.Models;
using System.Web.Helpers;
using System.Globalization;
using WebUI.Areas.Reports.Models;

namespace WebUI.Controllers
{
    public partial class ReportsController : Controller
    {
        #region Member Variables

        readonly IAuditedOperationsService _filesService;
        readonly IChartGeneratorService _chartGenerator;
        readonly ISessionHelper _sessionHelper;

        #endregion

        #region Constructor

        public ReportsController(IAuditedOperationsService filesService, IChartGeneratorService chartGenerator, ISessionHelper sessionHelper)
        {
            this._filesService = filesService;
            this._chartGenerator = chartGenerator;
            this._sessionHelper = sessionHelper;
        }

        #endregion

        #region Action Methods

        public virtual ViewResult Index()
        {
            var model = PopulateOverView(new FilterOperations());
            return View(model);
        }

        [HttpPost]
        public virtual PartialViewResult FilterOverview(FilterOperations filter)
        {
            var model = PopulateOverView(filter);
            return PartialView(MVC.Reports.Reports.Views._OverViewGrid, model);
        }

        public virtual ViewResult ReportsIndex(int operationType, string dir = null, int page = 1, string sort = "ID", string sortDir = "DESC")
        {
            _sessionHelper.SortColumn = sort;
            _sessionHelper.SortDirectionDesc = sortDir == "DESC";
            OperationType operation = (OperationType)operationType;
            var model = new FilesModel { Title = operation.ToString() };

            model.FilesFilter = new FilterOperations
            {
                operationType = operation,
                IsDir = !string.IsNullOrEmpty(dir)
            };

            FilterOperations filter = model.FilesFilter;

            if (_sessionHelper.Filter != null)
            {
                filter = _sessionHelper.Filter;
            }

            int totalCount;
            model.FilesList = _filesService.SearchFileActionsPaged(filter, page, out totalCount, sort, _sessionHelper.SortDirectionDesc);
            model.Chart = _chartGenerator.DrawReportsChart(model.FilesFilter, _filesService.SearchFileActions(filter));
            model.TotalCount = totalCount;
            return View(model);
        }

        [HttpPost]
        public virtual PartialViewResult FilterReports(FilterOperations filter, IEnumerable<string> columns)
        {
            _sessionHelper.Filter = filter;
            FilesModel model = new FilesModel();
            int totalCount;
            model.FilesList = _filesService.SearchFileActionsPaged(filter, 1, out totalCount, _sessionHelper.SortColumn, _sessionHelper.SortDirectionDesc);
            model.Chart = _chartGenerator.DrawReportsChart(filter, _filesService.SearchFileActions(filter));

            if (columns != null)
            {
                foreach (string column in columns)
                {
                    model.Columns[column] = true;
                }
            }

            return PartialView(MVC.Reports.Reports.Views._Records, model);
        }

        public virtual ViewResult OffHours()
        {
            var model = new FilesModel();
            model.FilesList = _filesService.SearchOffHours(new FilterOperations());
            model.Chart = _chartGenerator.DrawReportsChart(new FilterOperations(), model.FilesList);
            return View(model);
        }

        [HttpPost]
        [ActionName("OffHours")]
        public virtual PartialViewResult FilterOffHours(FilterOperations filter)
        {
            var model = new FilesModel();
            var results = _filesService.SearchOffHours(filter);
            model.Chart = _chartGenerator.DrawReportsChart(filter, results);
            return PartialView(MVC.Reports.Reports.Views._OffHoursGrid, model);
        }

        public virtual ViewResult BotsIndex(string botName, int page = 1, string sort = null, string sortDir = null)
        {
            var model = new FilesModel { Title = botName };
            model.FilesFilter = new FilterOperations { BotName = botName };
            int totalCount = 0;
            model.FilesList = _filesService.GetByBotName(botName, model.FilesFilter, ref totalCount, sort, sortDir, page);
            model.TotalCount = totalCount;
            model.Chart = _chartGenerator.DrawReportsChart(model.FilesFilter, model.FilesList);

            return View(model);
        }

        [HttpPost]
        public virtual PartialViewResult FilterBots(FilterOperations filter)
        {
            var model = new FilesModel();
            int totalCount = 0;
            model.FilesList = _filesService.GetByBotName(filter.BotName, filter, ref totalCount, null, null, 1);
            model.TotalCount = totalCount;
            model.Chart = _chartGenerator.DrawReportsChart(model.FilesFilter, model.FilesList);
            return PartialView(MVC.Reports.Reports.Views._BotsRecords, model);
        }

        [HttpGet]
        public virtual ViewResult MostActiveUsers()
        {
            IEnumerable<UserSummary> mostActiveUsers = _filesService.GetMostActiveUsers(new FilterOperations());

            return View(mostActiveUsers);
        }

        [HttpPost]
        public virtual PartialViewResult FilterMostActiveUsers(FilterOperations filter)
        {
            IEnumerable<UserSummary> model = _filesService.GetMostActiveUsers(filter);
            return PartialView(MVC.Reports.Reports.Views._MostActiveUsersGrid, model);
        }

        [HttpGet]
        public virtual ViewResult DeletionCompliance()
        {
            var model = new SpanViewModel
            {
                filesModel = new FilesModel
                {
                    ShowChart = false,
                    Title = Resources.DeletionCompliance
                }
            };

            return View(MVC.Reports.Reports.Views.SpanView, model);
        }

        [HttpPost]
        public virtual PartialViewResult DeletionCompliancePost(SpanViewModel deletionComplianceViewModel, IEnumerable<string> columns)
        {
            var model = new FilesModel { ShowChart = false };

            if (columns != null)
            {
                foreach (string column in columns)
                {
                    model.Columns[column] = true;
                }
            }

            model.FilesList = _filesService.GetDeletionCompliance((TimeSpans)deletionComplianceViewModel.Span, deletionComplianceViewModel.Value.Value);
            return PartialView(MVC.Reports.Reports.Views._Records, model);
        }

        [HttpGet]
        public virtual ViewResult Audit(string reportName, int page = 1, string sort = "ID", string sortDir = null)
        {
            int totalCount;

            var filter = new FilterOperations
            {
                operationType = OperationType.All,
                IsDir = false
            };
            IEnumerable<AuditedOperation> allOperations = _filesService.SearchFileActionsPaged(filter, page, out totalCount, sort, sortDir == "DESC");

            var model = new FilesModel
            {
                Chart = _chartGenerator.DrawReportsChart(filter, allOperations),
                Title = reportName,
                FilesList = allOperations,
                TotalCount = totalCount
            };

            model.FilesFilter.RenderOperationTypes = true;

            return View(MVC.Reports.Reports.Views.ViewNames.ReportsIndex, model);
        }

        [HttpGet]
        public virtual ViewResult MostAccessedDirectories()
        {
            IEnumerable<DirectoryCount> mostAccessedDirectories = _filesService.GetMostAccessedDirectories(new FilterOperations());

            return View(mostAccessedDirectories);
        }

        [HttpPost]
        public virtual PartialViewResult MostAccessedDirectoriesPost(FilterOperations filter)
        {
            IEnumerable<DirectoryCount> mostAccessedDirectories = _filesService.GetMostAccessedDirectories(filter);

            return PartialView(MVC.Reports.Reports.Views._MostAccessedDirectoriesGrid, mostAccessedDirectories);
        }

        [HttpGet]
        public virtual ViewResult AccessHistory()
        {
            var model = new SpanViewModel
            {
                filesModel = new FilesModel
                {
                    ShowChart = false,
                    Title = Resources.AccessHistory
                }
            };

            return View(MVC.Reports.Reports.Views.SpanView, model);
        }

        [HttpPost]
        public virtual PartialViewResult AccessHistoryPost(SpanViewModel spanViewModel, IEnumerable<string> columns)
        {
            var model = new FilesModel();

            if (columns != null)
            {
                foreach (string column in columns)
                {
                    model.Columns[column] = true;
                }
            }

            model.FilesList = _filesService.GetAccessHistory((TimeSpans)spanViewModel.Span, spanViewModel.Value.Value);
            return PartialView(MVC.Reports.Reports.Views._Records, model);
        }

        [HttpGet]
        public virtual ViewResult ChangedFiles()
        {
            var emptyFilter = new FilterOperations();
            IEnumerable<AuditedOperation> changedFiles = _filesService.GetChangedFiles(emptyFilter);

            var model = new FilesModel
            {
                Chart = _chartGenerator.DrawReportsChart(emptyFilter, changedFiles),
                FilesList = changedFiles,
                Title = Resources.Changed
            };

            return View(MVC.Reports.Reports.Views.ViewNames.ReportsIndex, model);
        }

        [HttpPost]
        public virtual PartialViewResult ChangedFilesSearch(FilterOperations filter)
        {
            IEnumerable<AuditedOperation> changedFiles = _filesService.GetChangedFiles(filter);

            var model = new FilesModel
            {
                Chart = _chartGenerator.DrawReportsChart(filter, changedFiles),
                FilesList = changedFiles
            };

            return PartialView(MVC.Reports.Reports.Views._Records, changedFiles);
        }

        [HttpGet]
        public virtual ViewResult FileSummary()
        {
            FileOperationsSummary fileOperationsSummary = _filesService.GetFileOperationsSummary(new FilterOperations());

            return View(fileOperationsSummary);
        }

        [HttpPost]
        public virtual PartialViewResult FileSummarySearch(FilterOperations filter)
        {
            FileOperationsSummary fileOperationsSummary = _filesService.GetFileOperationsSummary(filter);

            return PartialView(MVC.Reports.Reports.Views._fileSummaryGrid, fileOperationsSummary);
        }

        [HttpGet]
        public virtual ViewResult DeleteOperationsGroupedByDirectory()
        {
            IEnumerable<DirectoryOperations> deleteOperationsGroupedByDirectory = _filesService.GetDeleteOperationsGroupedByDirectory(new FilterOperations());
            var model = new DirectoryOperationsViewModel { DirectoryOperations = deleteOperationsGroupedByDirectory };
            return View(model);
        }

        [HttpPost]
        public virtual PartialViewResult DeleteOperationsGroupedByDirectorySearch(FilterOperations filter, IEnumerable<string> columns)
        {
            IEnumerable<DirectoryOperations> deleteOperationsGroupedByDirectory = _filesService.GetDeleteOperationsGroupedByDirectory(filter);

            var model = new DirectoryOperationsViewModel { DirectoryOperations = deleteOperationsGroupedByDirectory };

            if (columns != null)
            {
                foreach (string column in columns)
                {
                    model.Columns[column] = true;
                }
            }

            return PartialView(MVC.Reports.Reports.Views._DirectoriesGrid, model);
        }

        #endregion

        #region Private Methods

        private OverViewModel PopulateOverView(FilterOperations filter)
        {
            var model = new OverViewModel();
            int totalNumber;
            model.AccessedExtensions = _filesService.GetTopTenAccessedExtensions(filter, out totalNumber);
            model.TotalCount = totalNumber;

            model.Chart = _chartGenerator.DrawOverViewChart(model.AccessedExtensions);
            return model;
        }

        #endregion
    }
}